package com.dragon.common.spring.openapi;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 用于查找实现了特定接口的Controller的工具类
 * 程序改造后，暂时用不上了
 * 暂时用不上了，保留一下，研究学习
 */
@Component
public class ControllerImplementationFinder implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * 获取所有被 @Controller 或 @RestController 注解的Bean名称
     */
    public List<String> getAllControllerBeanNames() {
        return Arrays.stream(applicationContext.getBeanDefinitionNames())
                .filter(beanName -> {
                    Class<?> beanType = applicationContext.getType(beanName);
                    return beanType != null && isController(beanType);
                })
                .collect(Collectors.toList());
    }

    /**
     * 获取所有Controller Bean的Class对象
     */
    public List<Class<?>> getAllControllerClasses() {
        return getAllControllerBeanNames().stream()
                .map(beanName -> applicationContext.getType(beanName))
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 判断一个类是否是Controller
     */
    private boolean isController(Class<?> clazz) {
        return AnnotatedElementUtils.hasAnnotation(clazz, Controller.class) ||
                AnnotatedElementUtils.hasAnnotation(clazz, RestController.class);
    }

    /**
     * 查找所有实现了指定接口的Controller Bean
     * @param interfaceClass 要查找的接口Class
     * @return Bean名称到Bean实例的Map
     */
    public <T> Map<String, T> findControllersImplementingInterface(Class<T> interfaceClass) {
        Map<String, T> allBeansOfType = applicationContext.getBeansOfType(interfaceClass);

        // 过滤出Controller类型的Bean
        return allBeansOfType.entrySet().stream()
                .filter(entry -> isController(entry.getValue().getClass()))
                .collect(Collectors.toMap(
                        Map.Entry::getKey,
                        Map.Entry::getValue
                ));
    }

    /**
     * 查找所有实现了指定接口的Controller Class
     * @param interfaceClass 要查找的接口Class
     * @return Controller Class列表
     */
    public <T> List<Class<?>> findControllerClassesImplementingInterface(Class<T> interfaceClass) {
        return findControllersImplementingInterface(interfaceClass).values().stream()
                .map(Object::getClass)
                .collect(Collectors.toList());
    }

    /**
     * 查找所有实现了指定接口的Controller Bean名称
     * @param interfaceClass 要查找的接口Class
     * @return Bean名称列表
     */
    public <T> List<String> findControllerBeanNamesImplementingInterface(Class<T> interfaceClass) {
        return new ArrayList<>(findControllersImplementingInterface(interfaceClass).keySet());
    }

    /**
     * 检查指定的Bean是否是一个Controller并且实现了某个接口
     */
    public <T> boolean isControllerImplementingInterface(String beanName, Class<T> interfaceClass) {
        Object bean = applicationContext.getBean(beanName);
        return isController(bean.getClass()) && interfaceClass.isInstance(bean);
    }
}